<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    /*
        async 和 await 两种语法结合，可以让异步代码像同步代码一样执行。
        1. async函数
            async函数的返回值为Promise对象
            Promise对象的结果由async函数执行的返回值决定
        2. await表达式
            await必须写在async函数中；
            await右侧的表达式一般为Promise对象；
            await返回的是Promise成功的值；
            await的Promise失败了，就会抛出异常，需要通过try...catch捕获处理。
    */

    // async函数
    // 返回值只要不是一个Promise对象，就会自动包装为一个成功的Promise对象
    // 抛出错误，则返回值自动包装为一个失败的Promise对象 
    // 返回普通值 
    async function fn() {
        return '尚硅谷' 
    }
    const result = fn() 
    console.log(result) // Promise fulfilled 
    result.then((data) => {
        console.log(data) // 尚硅谷 
    })

    // 抛出错误 
    async function fn2() {
        throw new Error('手动制造一个错误')
    }
    const result2 = fn2() 
    console.log(result2) // Promise rejected 
    result2.catch((err) => {
        console.warn(err) // Error: 手动制造一个错误 
    })

    // 返回Promise 
    async function fn3() {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                // resolve('从数据库中查询到一条记录')
                reject('连接数据库超时')
            }, 1000)
        })
    }
    fn3().then((data) => {
        console.log('data', data) // data 从数据库中查询到一条记录
    }, (err) => {
        console.warn('err:', err) // err: 连接数据库超时 
    })


    // await 作用是等待Promise对象内的异步值返回，再继续往下执行 
    // 如果使用await，那他所在函数必须声明为async 
    const p1 = new Promise((resolve, reject) => {
        setTimeout(() => {
            // resolve('接口返回的数据')
            reject('请求接口失败')
        }, 1000)
    })
    async function fn5() {
        console.log('fn5 begin')
        try {
            let res = await p1 // 返回值res就是p1成功的值 
            console.log(res) // 接口返回的数据 
        } catch(e) {
            console.error(e) // 请求接口失败
        }
        
        console.log('fn5 end')
    }
    fn5() 
    console.log('我在fn5()后面') // fn5是一个异步函数，内部执行时遇到await就会阻塞，但是外部同时执行，互不影响 


</script>
</html>